package com.hq.communication;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程通信常用方式：
 * 1、Object:wait、notify、notifyAll
 * 2、Condition(肯跌顺) await、signal、signalAll
 * 3、CountDownLatch:用于某个线程A等待若干个线程执行完后，它才执行
 * 4、CyclicBarrier(赛可李可 败约耳):一组线程等待至某个状态之后再全部同步执行
 * 5、Semaphore:用于控制对某组资源的权限访问
 * <p>
 * 注意点；
 * 1、线程中调用wait notify方法的时候 要放到synchronized代码块中使用，确保代码段不会被多个线程调用
 * 如果不加sync关键字 执行notify  wait方法会爆  IllegalMonitorStateException
 * 2、Condition 必须配合lock锁来实现 await 和 signal.
 *
 * @author hq
 */
public class ThreadCommunicationDemo {
    public static void main(String[] args) {
        //通过Object wait notify 的方式实现线程之间的通信。
        Thread thread1 = new Thread(() -> ObjectOddEven.objectOdd(),"objectOdd");
        Thread thread2 = new Thread(() -> ObjectOddEven.objectEven(),"objectEven");
        thread1.start();
        thread2.start();

        //通过condition的 await signal方式  实现线程之间的通信。
        //Thread conditionThread1 = new Thread(() -> ConditionOddEven.conditionOdd(),"conditionOdd");
        //Thread conditionThread2 = new Thread(() -> ConditionOddEven.conditionEven(),"conditionEven");
        //conditionThread1.start();
        //conditionThread2.start();

        //教练训练成员，需要等待人员到齐后才能开始训练(发令枪，同时开始) 实现线程之间的通信。
        //Thread countDownThread1 = new Thread(() -> CountDownRacerCoach.Coach(),"教练");
        //Thread countDownThread2 = new Thread(() -> CountDownRacerCoach.racer(),"成员2");
        //Thread countDownThread3 = new Thread(() -> CountDownRacerCoach.racer(),"成员3");
        //Thread countDownThread4 = new Thread(() -> CountDownRacerCoach.racer(),"成员4");
        //countDownThread1.start();
        //countDownThread2.start();
        //countDownThread3.start();
        //countDownThread4.start();

        //一个事情 交给多个服务人员一起做，做事效率一样 同时开始  实现线程之间的通信。
        //Thread cyclicThread1 = new Thread(() -> CyclicBarrierStart.startThread(),"服务员1");
        //Thread cyclicThread2 = new Thread(() -> CyclicBarrierStart.startThread(),"服务员2");
        //Thread cyclicThread3 = new Thread(() -> CyclicBarrierStart.startThread(),"服务员3");
        //cyclicThread1.start();
        //cyclicThread2.start();
        //cyclicThread3.start();
    }
}



